{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Difference between an AST and ASR\n",
    "\n",
    "Let us take a simple Fortran code:\n",
    "```fortran\n",
    "integer function f(a, b) result(r)\n",
    "integer, intent(in) :: a, b\n",
    "integer :: c, d\n",
    "c = a + b - d\n",
    "r = c * a\n",
    "end function\n",
    "```\n",
    "and look at how the AST and ASR looks like.\n",
    "\n",
    "## AST"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%showast\n",
    "integer function f(a, b) result(r)\n",
    "integer, intent(in) :: a, b\n",
    "integer :: c, d\n",
    "c = a + b - d\n",
    "r = c * a\n",
    "end function"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The AST does not have any semantic information, but has nodes to represent declarations such as `integer, intent(in) :: a`. Variables such as `a` are represented by a `Name` node, and are not connected to their declarations yet."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ASR"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%showasr\n",
    "integer function f(a, b) result(r)\n",
    "integer, intent(in) :: a, b\n",
    "integer :: c, d\n",
    "c = a + b - d\n",
    "r = c * a\n",
    "end function"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ASR has all the semantic information (types, etc.), nodes like `Function` have a symbol table and do not have any declaration nodes. Variables are simply pointers to the symbol table.\n",
    "\n",
    "## Discussion\n",
    "\n",
    "The above was a simple example. Things get more apparent for more complicated examples, such as:\n",
    "```fortran\n",
    "integer function f2b(a) result(r)\n",
    "use gfort_interop, only: c_desc1_int32\n",
    "integer, intent(in) :: a(:)\n",
    "interface\n",
    "    integer function f2b_c_wrapper(a) bind(c, name=\"__mod1_MOD_f2b\")\n",
    "    use gfort_interop, only: c_desc1_t\n",
    "    type(c_desc1_t), intent(in) :: a\n",
    "    end function\n",
    "end interface\n",
    "r = f2b_c_wrapper(c_desc1_int32(a))\n",
    "end function\n",
    "```\n",
    "AST must represent all the `use` statements and the `interface` block, and keep things semantically consistent.\n",
    "\n",
    "ASR, on the other hand, keeps track of the `c_desc1_int32`, `c_desc1_t` and `f2b_c_wrapper` in the symbol table and it knows they are defined in the `gfort_interop` module, and so ASR does not have any of these declaration nodes.\n",
    "\n",
    "When converting from ASR to AST, LFortran will create all the appropriate AST declaration nodes automatically and correctly."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Fortran",
   "language": "fortran",
   "name": "fortran"
  },
  "language_info": {
   "file_extension": ".f90",
   "mimetype": "text/x-fortran",
   "name": "fortran",
   "version": "2018"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
